#include "vmgui.h"

#define R_BYTES 8
#define R_COLS 13

static WINDOW *wRegisters, *wRom, *wRam, *wOpt;
static PANEL *pRegs, *pRom, *pRam, *pOpt;

static char *last_instr;

void gui_init(void)
{
	initscr();
	keypad(stdscr, TRUE);
	noecho();
	cbreak();
	
	last_instr = "none";
	
	wRegisters = newwin(4, COLS, 0, 0);
	wRom = newwin(15, COLS/2, 4, 0);
	wRam = newwin(15, COLS/2, 4, COLS/2);
	wOpt = newwin(4, COLS, 19, 0);
	
	box(wRegisters, 0, 0);
	
	mvwprintw(wRegisters, 0, 1, "[Registers]");
	mvwprintw(wRom, 0, 1, "[ROM]");
	mvwprintw(wRam, 0, 1, "[RAM]");
	mvwprintw(wOpt, 0, 1, "[Commands]");
	
	pRegs = new_panel(wRegisters);
	pRom = new_panel(wRom);
	pRam = new_panel(wRam);
	pOpt = new_panel(wOpt);
}

void gui_draw()
{
	wclear(wRom);
	wclear(wRam);
	wclear(wOpt);
	
	
	box(wRom, 0, 0);
	box(wRam, 0, 0);
	box(wOpt, 0, 0);
	
	mvwprintw(wRegisters, 1, 2, "A: 0x%.2X", r.AF.B.A);
	mvwprintw(wRegisters, 2, 2, "F: 0x%.2X", r.AF.B.F);
	mvwprintw(wRegisters, 1, 10, "B: 0x%.2X", r.BC.B.B);
	mvwprintw(wRegisters, 2, 10, "C: 0x%.2X", r.BC.B.C);
	mvwprintw(wRegisters, 1, 18, "D: 0x%.2X", r.DE.B.D);
	mvwprintw(wRegisters, 2, 18, "E: 0x%.2X", r.DE.B.E);
	mvwprintw(wRegisters, 1, 26, "H: 0x%.2X", r.HL.B.H);
	mvwprintw(wRegisters, 2, 26, "L: 0x%.2X", r.HL.B.L);
	
	mvwprintw(wRegisters, 1, 37, "HL: 0x%.4X", r.HL.HL);
	mvwprintw(wRegisters, 2, 37, "BC: 0x%.4X", r.BC.BC);
	mvwprintw(wRegisters, 1, 48, "DE: 0x%.4X", r.DE.DE);
	mvwprintw(wRegisters, 2, 48, "SP: 0x%.4X", r.SP);
	mvwprintw(wRegisters, 1, 63, "PC: 0x%.4X", r.PC);
	mvwprintw(wRegisters, 2, 63, "Flags: 00000000");
	
	UINT16 startPC = r.PC - (r.PC%8);
	
	for (int i = 0; i < R_COLS; ++i)
	{
		mvwprintw(wRom, 1+i, 2+2, "0x%.4X", startPC);
		
		for (int j = 0; j < R_BYTES; ++j)
			if (startPC + j < rom_size())
			{
				if (startPC + j == r.PC)
				{
					mvwprintw(wRom, 1+i, 10+1+(j*3), ">");
					mvwprintw(wRom, 1+i, 10+4+(j*3), "<");
				}
					
				mvwprintw(wRom, 1+i, 10+2+(j*3), "%.2X", mem_read(startPC + j));
		
			}
				
		startPC += 8;
	}
	
	for (int i = 0; i < R_COLS; ++i)
	{
		mvwprintw(wRam, 1+i, 2+2, "0x0000");
		
		for (int j = 0; j < R_BYTES; ++j)
			mvwprintw(wRam, 1+i, 10+2+(j*3), "00");
	}
	
	mvwprintw(wOpt, 1, 2, "(S)tep instruction");
	mvwprintw(wOpt, 2, 2, "(Q)uit");
	mvwprintw(wOpt, 1, 30, "Last Instruction: %s", last_instr);
	
	mvprintw(23, COLS - 16, "-:[Z80-GB VM]:-");
	
	update_panels();
	doupdate();
	//refresh();
}

void gui_set_last_instr(char *instr)
{
	last_instr = instr;
}

void gui_end(void)
{
	endwin();
}
